home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / Direct3D / BumpMapping / BumpWaves / BumpWaves.cpp next >
C/C++ Source or Header  |  2001-10-31  |  23KB  |  638 lines

  1. //-----------------------------------------------------------------------------
  2. // File: BumpWaves.cpp
  3. //
  4. // Desc: Code to simulate reflections off waves using bumpmapping.
  5. //
  6. //       Note: This code uses the D3D Framework helper library.
  7. //
  8. // Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
  9. //-----------------------------------------------------------------------------
  10. #define STRICT
  11. #include <tchar.h>
  12. #include <math.h>
  13. #include <stdio.h>
  14. #include <D3DX8.h>
  15. #include "D3DApp.h"
  16. #include "D3DFont.h"
  17. #include "D3DUtil.h"
  18. #include "DXUtil.h"
  19.  
  20.  
  21.  
  22.  
  23. //-----------------------------------------------------------------------------
  24. // Function prototypes and global (or static) variables
  25. //-----------------------------------------------------------------------------
  26. inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
  27.  
  28. struct VERTEX
  29. {
  30.     D3DXVECTOR3 p;
  31.     FLOAT       tu, tv;
  32. };
  33.  
  34. #define D3DFVF_VERTEX (D3DFVF_XYZ|D3DFVF_TEX1)
  35.  
  36.  
  37. //-----------------------------------------------------------------------------
  38. // Name: class CMyD3DApplication
  39. // Desc: Application class. The base class (CD3DApplication) provides the 
  40. //       generic functionality needed in all Direct3D samples. CMyD3DApplication 
  41. //       adds functionality specific to this sample program.
  42. //-----------------------------------------------------------------------------
  43. class CMyD3DApplication : public CD3DApplication
  44. {
  45.     CD3DFont*               m_pFont;
  46.     LPDIRECT3DVERTEXBUFFER8 m_pBackgroundVB;
  47.     LPDIRECT3DTEXTURE8      m_pBackgroundTexture;
  48.  
  49.     LPDIRECT3DVERTEXBUFFER8 m_pWaterVB;
  50.     LPDIRECT3DTEXTURE8      m_psBumpMap;
  51.     D3DXMATRIX              m_matBumpMat;
  52.  
  53.     LPDIRECT3DTEXTURE8 CreateBumpMap( DWORD, DWORD, D3DFORMAT );
  54.     HRESULT ConfirmDevice( D3DCAPS8*, DWORD, D3DFORMAT );
  55.  
  56. protected:
  57.     HRESULT OneTimeSceneInit();
  58.     HRESULT InitDeviceObjects();
  59.     HRESULT RestoreDeviceObjects();
  60.     HRESULT InvalidateDeviceObjects();
  61.     HRESULT DeleteDeviceObjects();
  62.     HRESULT Render();
  63.     HRESULT FrameMove();
  64.     HRESULT FinalCleanup();
  65.     HRESULT SetEMBMStates();
  66.  
  67.     UINT m_n;               // Number of vertices in the ground grid along X
  68.     UINT m_m;               // Number of vertices in the ground grid along Z
  69.     UINT m_nTriangles;      // Number of triangles in the ground grid
  70.  
  71.     DWORD m_dwVertexShader;   // Vertex shader handle for the bump waves
  72.     BOOL  m_bUseVertexShader; // Whether to use vertex shader or FF pipeline
  73.  
  74. public:
  75.     CMyD3DApplication();
  76. };
  77.  
  78.  
  79. //-----------------------------------------------------------------------------
  80. //
  81. // Vertex shader code for bump waves -- this is used when the fixed-function
  82. // approach is not supported by the device
  83. //
  84. // const[0 - 2] Transformation matrix to the camera space, combined with texture
  85. //              transformation matrix, because position in the camera space is 
  86. //              used as texture coordinates. Texture transfoX and Y row are 
  87. //              multiplied by 0.8 to make texture transformation.
  88. //
  89. // const[3-7]   Transformation matrix to the projection space
  90. // const[8]     [0.5, -0.5, 0, 0]
  91. //
  92. // v[0]   - position
  93. // v[1]   - texture coordinates for stage 0
  94. //
  95. char g_strVertexShader[] = 
  96.     "vs.1.1\n"
  97.     "m4x4 oPos, v0, c3 ; transform position to the projection space\n"
  98.     "; Compute vertex position in the camera space - this is our texture coordinates\n"
  99.     "dp4 r0.x, v0, c0 \n"
  100.     "dp4 r0.y, v0, c1 \n"
  101.     "dp4 r0.z, v0, c2 \n"
  102.     "; Do the rest of texture transform (first part was combined with the camera matrix) \n"
  103.     "rcp r0.z, r0.z \n"
  104.     "mad oT1.x, r0.x, r0.z, c8.x \n"
  105.     "mad oT1.y, r0.y, r0.z, c8.y \n"
  106.     "mov oT0.xy, v1     ; Copy input texture coordinates for the stage 0\n";
  107.  
  108.  
  109.  
  110.  
  111. //-----------------------------------------------------------------------------
  112. // Name: WinMain()
  113. // Desc: Entry point to the program. Initializes everything, and goes into a
  114. //       message-processing loop. Idle time is used to render the scene.
  115. //-----------------------------------------------------------------------------
  116. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  117. {
  118.     CMyD3DApplication d3dApp;
  119.  
  120.     if( FAILED( d3dApp.Create( hInst ) ) )
  121.         return 0;
  122.  
  123.     return d3dApp.Run();
  124. }
  125.  
  126.  
  127.  
  128.  
  129. //-----------------------------------------------------------------------------
  130. // Name: CMyD3DApplication()
  131. // Desc: Application constructor. Sets attributes for the app.
  132. //-----------------------------------------------------------------------------
  133. CMyD3DApplication::CMyD3DApplication()
  134. {
  135.     m_strWindowTitle    = _T("BumpWaves: Using BumpMapping For Waves");
  136.     m_bUseDepthBuffer   = FALSE;
  137.  
  138.     m_pFont              = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
  139.     m_psBumpMap          = NULL;
  140.     m_pBackgroundTexture = NULL;
  141.     m_pBackgroundVB      = NULL;
  142.     m_pWaterVB           = NULL;
  143.  
  144.     // The following are set in InitDeviceObjects
  145.     m_n = 0;
  146.     m_m = 0;
  147.     m_nTriangles = 0;
  148.  
  149.     m_dwVertexShader = 0;
  150.     m_bUseVertexShader = FALSE;
  151. }
  152.  
  153.  
  154.  
  155.  
  156. //-----------------------------------------------------------------------------
  157. // Name: OneTimeSceneInit()
  158. // Desc: Called during initial app startup, this function performs all the
  159. //       permanent initialization.
  160. //-----------------------------------------------------------------------------
  161. HRESULT CMyD3DApplication::OneTimeSceneInit()
  162. {
  163.     return S_OK;
  164. }
  165.  
  166.  
  167.  
  168.  
  169. //-----------------------------------------------------------------------------
  170. // Name: FrameMove()
  171. // Desc: Called once per frame, the call is the entry point for animating
  172. //       the scene.
  173. //-----------------------------------------------------------------------------
  174. HRESULT CMyD3DApplication::FrameMove()
  175. {
  176.     // Setup the bump matrix
  177.     // Min r is 0.04 if amplitude is 32 to miss temporal aliasing
  178.     // Max r is 0.16 for amplitude is 8 to miss spatial aliasing
  179.     FLOAT r = 0.04f;
  180.     m_matBumpMat._11 =  r * cosf( m_fTime * 9.0f );
  181.     m_matBumpMat._12 = -r * sinf( m_fTime * 9.0f );
  182.     m_matBumpMat._21 =  r * sinf( m_fTime * 9.0f );
  183.     m_matBumpMat._22 =  r * cosf( m_fTime * 9.0f );
  184.  
  185.     return S_OK;
  186. }
  187.  
  188.  
  189.  
  190.  
  191. //-----------------------------------------------------------------------------
  192. // Name: Render()
  193. // Desc: Called once per frame, the call is the entry point for 3d
  194. //       rendering. This function sets up render states, clears the
  195. //       viewport, and renders the scene.
  196. //-----------------------------------------------------------------------------
  197. HRESULT CMyD3DApplication::Render()
  198. {
  199.     // Clear the render target
  200.     m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0L );
  201.     
  202.     // Begin the scene
  203.     if( FAILED( m_pd3dDevice->BeginScene() ) )
  204.         return S_OK;
  205.  
  206.     // Set up texture stage states for the background
  207.     m_pd3dDevice->SetTexture( 0, m_pBackgroundTexture );
  208.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
  209.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  210.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
  211.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
  212.  
  213.     // Render the background
  214.     m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX );
  215.     m_pd3dDevice->SetStreamSource( 0, m_pBackgroundVB, sizeof(VERTEX) );
  216.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
  217.  
  218.     // Render the water
  219.     SetEMBMStates();
  220.     if( m_bUseVertexShader )
  221.         m_pd3dDevice->SetVertexShader( m_dwVertexShader );
  222.     else
  223.         m_pd3dDevice->SetVertexShader( D3DFVF_VERTEX );
  224.  
  225.     m_pd3dDevice->SetStreamSource( 0, m_pWaterVB, sizeof(VERTEX) );
  226.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, m_nTriangles );
  227.  
  228.     // Output statistics
  229.     m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
  230.     m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
  231.     TCHAR strInfo[100];
  232.     if( m_bUseVertexShader )
  233.         lstrcpy( strInfo, TEXT("Using Vertex Shader") );
  234.     else
  235.         lstrcpy( strInfo, TEXT("Using Fixed-Function Vertex Pipeline") );
  236.     m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,255,255), strInfo );
  237.  
  238.     // End the scene.
  239.     m_pd3dDevice->EndScene();
  240.  
  241.     return S_OK;
  242. }
  243.  
  244.  
  245.  
  246.  
  247. //-----------------------------------------------------------------------------
  248. // Name: SetEMBMStates()
  249. // Desc: 
  250. //-----------------------------------------------------------------------------
  251. HRESULT CMyD3DApplication::SetEMBMStates()
  252. {
  253.     // Set up texture stage 0's states for the bumpmap
  254.     m_pd3dDevice->SetTexture( 0, m_psBumpMap );
  255.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP );
  256.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP );
  257.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT00,   F2DW( m_matBumpMat._11 ) );
  258.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT01,   F2DW( m_matBumpMat._12 ) );
  259.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT10,   F2DW( m_matBumpMat._21 ) );
  260.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT11,   F2DW( m_matBumpMat._22 ) );
  261.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_BUMPENVMAP );
  262.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  263.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
  264.  
  265.     // Set up texture stage 1's states for the environment map
  266.     m_pd3dDevice->SetTexture( 1, m_pBackgroundTexture );
  267.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  268.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
  269.  
  270.     if( m_bUseVertexShader )
  271.     {
  272.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
  273.     }
  274.     else
  275.     {
  276.         // Set up projected texture coordinates
  277.         // tu = (0.8x + 0.5z) / z
  278.         // tv = (0.8y - 0.5z) / z
  279.         D3DXMATRIX mat;
  280.         mat._11 = 0.8f; mat._12 = 0.0f; mat._13 = 0.0f;
  281.         mat._21 = 0.0f; mat._22 = 0.8f; mat._23 = 0.0f;
  282.         mat._31 = 0.5f; mat._32 =-0.5f; mat._33 = 1.0f;
  283.         mat._41 = 0.0f; mat._42 = 0.0f; mat._43 = 0.0f;
  284.  
  285.         m_pd3dDevice->SetTransform( D3DTS_TEXTURE1, &mat );
  286.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3|D3DTTFF_PROJECTED );
  287.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
  288.  
  289.     }
  290.     return S_OK;
  291. }
  292.  
  293.  
  294.  
  295.  
  296. //-----------------------------------------------------------------------------
  297. // Name: CreateBumpMap()
  298. // Desc: Creates a bumpmap
  299. //-----------------------------------------------------------------------------
  300. LPDIRECT3DTEXTURE8 CMyD3DApplication::CreateBumpMap( DWORD dwWidth, DWORD dwHeight,
  301.                                                      D3DFORMAT d3dBumpFormat )
  302. {
  303.     LPDIRECT3DTEXTURE8 psBumpMap;
  304.  
  305.     // Check if the device can create the format
  306.     if( FAILED( m_pD3D->CheckDeviceFormat( m_d3dCaps.AdapterOrdinal,
  307.                                            m_d3dCaps.DeviceType,
  308.                                            m_d3dsdBackBuffer.Format,
  309.                                            0, D3DRTYPE_TEXTURE, d3dBumpFormat ) ) )
  310.         return NULL;
  311.  
  312.     // Create the bump map texture
  313.     if( FAILED( m_pd3dDevice->CreateTexture( dwWidth, dwHeight, 1, 0 /* Usage */,
  314.                                              d3dBumpFormat, D3DPOOL_MANAGED,
  315.                                              &psBumpMap ) ) )
  316.         return NULL;
  317.  
  318.     // Lock the surface and write in some bumps for the waves
  319.     D3DLOCKED_RECT d3dlr;
  320.     psBumpMap->LockRect( 0, &d3dlr, 0, 0 );
  321.     CHAR* pDst = (CHAR*)d3dlr.pBits;
  322.     CHAR  iDu, iDv;
  323.  
  324.     for( DWORD y=0; y<dwHeight; y++ )
  325.     {
  326.         CHAR* pPixel = pDst;
  327.  
  328.         for( DWORD x=0; x<dwWidth; x++ )
  329.         {
  330.             FLOAT fx = x/(FLOAT)dwWidth - 0.5f;
  331.             FLOAT fy = y/(FLOAT)dwHeight - 0.5f;
  332.  
  333.             FLOAT r = sqrtf( fx*fx + fy*fy );
  334.  
  335.             iDu  = (CHAR)( 64 * cosf( 300.0f * r ) * expf( -r * 5.0f ) );
  336.             iDu += (CHAR)( 32 * cosf( 150.0f * ( fx + fy ) ) );
  337.             iDu += (CHAR)( 16 * cosf( 140.0f * ( fx * 0.85f - fy ) ) );
  338.  
  339.             iDv  = (CHAR)( 64 * sinf( 300.0f * r ) * expf( -r * 5.0f ) );
  340.             iDv += (CHAR)( 32 * sinf( 150.0f * ( fx + fy ) ) );
  341.             iDv += (CHAR)( 16 * sinf( 140.0f * ( fx * 0.85f - fy ) ) );
  342.  
  343.             *pPixel++ = iDu;
  344.             *pPixel++ = iDv;
  345.         }
  346.         pDst += d3dlr.Pitch;
  347.     }
  348.     psBumpMap->UnlockRect(0);
  349.  
  350.     return psBumpMap;
  351. }
  352.  
  353.  
  354.  
  355.  
  356. //-----------------------------------------------------------------------------
  357. // Name: InitDeviceObjects()
  358. // Desc: Initialize scene objects
  359. //-----------------------------------------------------------------------------
  360. HRESULT CMyD3DApplication::InitDeviceObjects()
  361. {
  362.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  363.  
  364.     // Load the texture for the background image
  365.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Lake.bmp"),
  366.                                        &m_pBackgroundTexture, D3DFMT_R5G6B5 ) ) )
  367.         return D3DAPPERR_MEDIANOTFOUND;
  368.  
  369.     // Create the bumpmap. 
  370.     m_psBumpMap = CreateBumpMap( 256, 256, D3DFMT_V8U8 );
  371.     if( NULL == m_psBumpMap )
  372.         return E_FAIL;
  373.  
  374.     // Create a square for rendering the background
  375.     if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(VERTEX),
  376.                                                   D3DUSAGE_WRITEONLY, D3DFVF_VERTEX,
  377.                                                   D3DPOOL_MANAGED, &m_pBackgroundVB ) ) )
  378.         return E_FAIL;
  379.     VERTEX* v;
  380.     m_pBackgroundVB->Lock( 0, 0, (BYTE**)&v, 0 );
  381.     v[0].p  = D3DXVECTOR3(-1000.0f,    0.0f, 0.0f );
  382.     v[1].p  = D3DXVECTOR3(-1000.0f, 1000.0f, 0.0f );
  383.     v[2].p  = D3DXVECTOR3( 1000.0f,    0.0f, 0.0f );
  384.     v[3].p  = D3DXVECTOR3( 1000.0f, 1000.0f, 0.0f );
  385.     v[0].tu = 0.0f; v[0].tv = 147/256.0f;
  386.     v[1].tu = 0.0f; v[1].tv = 0.0f;
  387.     v[2].tu = 1.0f; v[2].tv = 147/256.0f;
  388.     v[3].tu = 1.0f; v[3].tv = 0.0f;
  389.     m_pBackgroundVB->Unlock();
  390.  
  391.     // See if EMBM and projected vertices are supported at the same time
  392.     // in the fixed-function shader.  If not, switch to using a vertex shader.
  393.     m_bUseVertexShader = FALSE;
  394.     SetEMBMStates();
  395.     DWORD dwPasses;
  396.     if( FAILED( m_pd3dDevice->ValidateDevice( &dwPasses ) ) )
  397.         m_bUseVertexShader = TRUE;
  398.  
  399.     // If D3DPTEXTURECAPS_PROJECTED is set, projected textures are computed
  400.     // per pixel, so this sample will work fine with just a quad for the water
  401.     // model.  If it's not set, textures are projected per vertex rather than 
  402.     // per pixel, so distortion will be visible unless we use more vertices.
  403.     if( m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_PROJECTED && !m_bUseVertexShader)
  404.     {
  405.         m_n = 2;               // Number of vertices in the ground grid along X
  406.         m_m = 2;               // Number of vertices in the ground grid along Z
  407.     }
  408.     else
  409.     {
  410.         m_n = 8;               // Number of vertices in the ground grid along X
  411.         m_m = 8;               // Number of vertices in the ground grid along Z
  412.     }
  413.     m_nTriangles = (m_n-1)*(m_m-1)*2;   // Number of triangles in the ground
  414.  
  415.     // Create a square grid m_n*m_m for rendering the water
  416.     if( FAILED( m_pd3dDevice->CreateVertexBuffer( m_nTriangles*3*sizeof(VERTEX),
  417.                                                   D3DUSAGE_WRITEONLY, D3DFVF_VERTEX,
  418.                                                   D3DPOOL_MANAGED, &m_pWaterVB ) ) )
  419.         return E_FAIL;
  420.     m_pWaterVB->Lock( 0, 0, (BYTE**)&v, 0 );
  421.     float dX = 2000.0f/(m_n-1);
  422.     float dZ = 1250.0f/(m_m-1);
  423.     float x0 = -1000;
  424.     float z0 = -1250;
  425.     float dU = 1.0f/(m_n-1);
  426.     float dV = 0.7f/(m_m-1);
  427.     UINT k = 0;
  428.     for (UINT z=0; z < (m_m-1); z++)
  429.     {
  430.         for (UINT x=0; x < (m_n-1); x++)
  431.         {
  432.             v[k].p  = D3DXVECTOR3(x0 + x*dX, 0.0f, z0 + z*dZ );
  433.             v[k].tu = x*dU; 
  434.             v[k].tv = z*dV;
  435.             k++;
  436.             v[k].p  = D3DXVECTOR3(x0 + x*dX, 0.0f, z0 + (z+1)*dZ );
  437.             v[k].tu = x*dU; 
  438.             v[k].tv = (z+1)*dV;
  439.             k++;
  440.             v[k].p  = D3DXVECTOR3(x0 + (x+1)*dX, 0.0f, z0 + (z+1)*dZ );
  441.             v[k].tu = (x+1)*dU; 
  442.             v[k].tv = (z+1)*dV;
  443.             k++;
  444.             v[k].p  = D3DXVECTOR3(x0 + x*dX, 0.0f, z0 + z*dZ );
  445.             v[k].tu = x*dU; 
  446.             v[k].tv = z*dV;
  447.             k++;
  448.             v[k].p  = D3DXVECTOR3(x0 + (x+1)*dX, 0.0f, z0 + (z+1)*dZ );
  449.             v[k].tu = (x+1)*dU; 
  450.             v[k].tv = (z+1)*dV;
  451.             k++;
  452.             v[k].p  = D3DXVECTOR3(x0 + (x+1)*dX, 0.0f, z0 + z*dZ );
  453.             v[k].tu = (x+1)*dU; 
  454.             v[k].tv = z*dV;
  455.             k++;
  456.         }
  457.     }
  458.     m_pWaterVB->Unlock();
  459.  
  460.     return S_OK;
  461. }
  462.  
  463.  
  464.  
  465.  
  466. //-----------------------------------------------------------------------------
  467. // Name: RestoreDeviceObjects()
  468. // Desc: Initialize scene objects
  469. //-----------------------------------------------------------------------------
  470. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  471. {
  472.     HRESULT hr;
  473.  
  474.     m_pFont->RestoreDeviceObjects();
  475.  
  476.     // Set the transform matrices
  477.     D3DXVECTOR3 vEyePt(    0.0f, 400.0f, -1650.0f );
  478.     D3DXVECTOR3 vLookatPt( 0.0f,   0.0f,     0.0f );
  479.     D3DXVECTOR3 vUpVec(    0.0f,   1.0f,     0.0f );
  480.     D3DXMATRIX matWorld, matView, matProj;
  481.  
  482.     D3DXMatrixIdentity( &matWorld );
  483.     D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  484.     D3DXMatrixPerspectiveFovLH( &matProj, 1.00f, 1.0f, 1.0f, 10000.0f );
  485.     m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  486.     m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
  487.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  488.  
  489.     // Set any appropiate state
  490.     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,        0xffffffff );
  491.     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   TRUE );
  492.     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  493.  
  494.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  495.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  496.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  497.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  498.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  499.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  500.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  501.  
  502.     if ( m_bUseVertexShader )
  503.     {
  504.         DWORD dwWaveDecl[] =
  505.         {
  506.             D3DVSD_STREAM( 0 ),
  507.             D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // Position
  508.             D3DVSD_REG( 1, D3DVSDT_FLOAT2 ), // Tex coords
  509.             D3DVSD_END()
  510.         };
  511.  
  512.         LPD3DXBUFFER pCode;
  513.         if( FAILED( hr = D3DXAssembleShader( g_strVertexShader, 
  514.                                              strlen(g_strVertexShader), 
  515.                                              0, NULL, &pCode, NULL ) ) )
  516.         {
  517.             return hr;
  518.         }
  519.         hr = m_pd3dDevice->CreateVertexShader( dwWaveDecl,
  520.                                                (DWORD*)pCode->GetBufferPointer(),
  521.                                                &m_dwVertexShader, 0);
  522.         if( FAILED( hr ) )
  523.         {
  524.             return hr;
  525.         }
  526.         pCode->Release();
  527.  
  528.         D3DXMATRIX matCamera, matFinal;
  529.         D3DXMatrixMultiply( &matCamera, &matWorld, &matView );
  530.         D3DXMatrixMultiply( &matFinal, &matCamera, &matProj );
  531.         D3DXMatrixTranspose(&matCamera, &matCamera);
  532.         D3DXMatrixTranspose(&matFinal, &matFinal);
  533.         matCamera(0, 0) *= 0.8f;
  534.         matCamera(0, 1) *= 0.8f;
  535.         matCamera(0, 2) *= 0.8f;
  536.         matCamera(0, 3) *= 0.8f;
  537.         matCamera(1, 0) *= 0.8f;
  538.         matCamera(1, 1) *= 0.8f;
  539.         matCamera(1, 2) *= 0.8f;
  540.         matCamera(1, 3) *= 0.8f;
  541.         if (FAILED( hr = m_pd3dDevice->SetVertexShaderConstant(0, &matCamera, 3) ) )
  542.         {
  543.             return hr;
  544.         }
  545.         if (FAILED( hr = m_pd3dDevice->SetVertexShaderConstant(3, &matFinal, 4) ) )
  546.         {
  547.             return hr;
  548.         }
  549.         FLOAT data[4] = {0.5f, -0.5f, 0, 0};
  550.         if (FAILED( hr = m_pd3dDevice->SetVertexShaderConstant(8, &data, 1) ) )
  551.         {
  552.             return hr;
  553.         }
  554.     }
  555.  
  556.     return S_OK;
  557. }
  558.  
  559.  
  560.  
  561.  
  562. //-----------------------------------------------------------------------------
  563. // Name: InvalidateDeviceObjects()
  564. // Desc:
  565. //-----------------------------------------------------------------------------
  566. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  567. {
  568.     m_pFont->InvalidateDeviceObjects();
  569.     if( m_dwVertexShader != 0 )
  570.     {
  571.         m_pd3dDevice->DeleteVertexShader( m_dwVertexShader );
  572.         m_dwVertexShader = 0;
  573.     }
  574.  
  575.     return S_OK;
  576. }
  577.  
  578.  
  579.  
  580.  
  581. //-----------------------------------------------------------------------------
  582. // Name: DeleteDeviceObjects()
  583. // Desc: Called when the app is exiting, or the device is being changed,
  584. //       this function deletes any device dependent objects.
  585. //-----------------------------------------------------------------------------
  586. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  587. {
  588.     m_pFont->DeleteDeviceObjects();
  589.     SAFE_RELEASE( m_pBackgroundTexture );
  590.     SAFE_RELEASE( m_psBumpMap );
  591.     SAFE_RELEASE( m_pBackgroundVB );
  592.     SAFE_RELEASE( m_pWaterVB );
  593.  
  594.     return S_OK;
  595. }
  596.  
  597.  
  598.  
  599.  
  600. //-----------------------------------------------------------------------------
  601. // Name: FinalCleanup()
  602. // Desc: Called before the app exits, this function gives the app the chance
  603. //       to cleanup after itself.
  604. //-----------------------------------------------------------------------------
  605. HRESULT CMyD3DApplication::FinalCleanup()
  606. {
  607.     SAFE_DELETE( m_pFont );
  608.     return S_OK;
  609. }
  610.  
  611.  
  612.  
  613.  
  614. //-----------------------------------------------------------------------------
  615. // Name: ConfirmDevice()
  616. // Desc: Called during device intialization, this code checks the device
  617. //       for some minimum set of capabilities
  618. //-----------------------------------------------------------------------------
  619. HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
  620.                                           D3DFORMAT Format )
  621. {
  622.     // Device must be able to do bumpmapping
  623.     if( 0 == ( pCaps->TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP ) )
  624.         return E_FAIL;
  625.  
  626.     // Accept devices that can create D3DFMT_V8U8 textures
  627.     if( SUCCEEDED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
  628.                                               pCaps->DeviceType, Format,
  629.                                               0, D3DRTYPE_TEXTURE,
  630.                                               D3DFMT_V8U8 ) ) )
  631.         return S_OK;
  632.  
  633.     // Else, reject the device
  634.     return E_FAIL;
  635. }
  636.  
  637.  
  638.